package cn.itsource.system.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.itsource.system.domain.Employee;
import cn.itsource.system.domain.Logininfo;
import cn.itsource.system.mapper.EmployeeMapper;
import cn.itsource.system.mapper.LogininfoMapper;
import cn.itsource.system.query.EmployeeQuery;
import cn.itsource.system.service.IEmployeeService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;


@Service
// Transactional：用来控制事务的注解；readOnly：只读；propagation：事务传播机制
//  Propagation.SUPPORTS：支持当前事务，如果没有当前事务，就以非事务方法执行
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)

public class EmlpoyeeServiceImpl implements IEmployeeService {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Transactional
    @Override
    public void add(Employee employee) {
        // hutool生成的盐值和加密
        // RandomUtil.randomString 获得一个随机的字符串（只包含数字和字符） ，32位
        String salt = RandomUtil.randomString(32);
        //  SecureUtil.md5 加密
        String md5Psd = SecureUtil.md5(employee.getPassword() + salt);

       // 加盐加密
        employee.setSalt(salt);
        employee.setPassword(md5Psd);

        // 将员工的信息添加到tb_logininfo表里
        Logininfo logininfo = new Logininfo();
        //  BeanUtils.copyProperties(源对象,目标对象); 根据属性同名原则进行属性值的复制——将源对象的属性值复制到目标对象对应的属性值
        BeanUtils.copyProperties(employee,logininfo);
        // 由于只能复制相同的字段所以需要把没有复制的字段添加完成
        // 类型 - 0管理员，1用户 设置员工的类型为0
        logininfo.setType(0);
        // 员工状态 - 1启用，0禁用 根据员工的状态设置tb_logininfo表员工的禁用状态
        logininfo.setDisable(employee.getState()==0?false:true);
        // 将logininfo添加到tb_logininfo表里，添加后由于设置了id为主键自增长，所以会自动生成自增的id
        logininfoMapper.add(logininfo);

        // 设置员工的logininfoId为logininfo的id
        employee.setLogininfoId(logininfo.getId());

        // 将员工信息添加到tb_employee表
        employeeMapper.add(employee);

       // 添加员工的角色信息到tb_employee_role表
        if (employee.getMyRoles().size() > 0){ // 判断员工是否有角色，不会空指针因为domain里设置了private List<String> roles = new ArrayList<>();
            employeeMapper.addEmpRoles(employee);
        }
    }

    @Transactional
    @Override
    public void update(Employee employee) {
        // 将员工信息更新到数据库
        employeeMapper.update(employee);

        // 根据员工id删除员工在tb_employee_role表的所有角色
        employeeMapper.delEmpRoles(employee.getId());
        // 添加员工的角色信息到tb_employee_role表
        if (employee.getMyRoles().size() > 0){ // 判断传来的员工信息里是否有角色
            employeeMapper.addEmpRoles(employee);
        }

        Logininfo logininfo = new Logininfo();
        BeanUtils.copyProperties(employee,logininfo);
        // 复制后的logininfoid为员工的id所以需要在设置为员工的logininfoId
        logininfo.setId(employee.getLogininfoId());
        logininfo.setType(0);
        logininfo.setDisable(employee.getState()==0?false:true);
        // 将logininfo对象修改后的信息放到tb_logininfo表里
        logininfoMapper.update(logininfo);

    }

    @Transactional
    @Override
    public void delete(Long id) {
        // 根据id获取当前员工的对象
        Employee employee = employeeMapper.getOne(id);
        // 根据当前员工的logininfoId删除tb_logininfo表里的数据
        logininfoMapper.delete(employee.getLogininfoId());

        // 先删除tb_employee_role表的员工的所有角色，然后在删除tb_employee表里的员工信息，有事务管理（原子性：要么全部成功，要么全部失败）
        // 根据员工id删除员工在tb_employee_role表的所有角色
        employeeMapper.delEmpRoles(id);
       // 将从数据库中删除员工信息
        employeeMapper.delete(id);
    }

    @Override
    public Employee getOne(Long id) {
        return employeeMapper.getOne(id);
    }

    @Override
    public List<Employee> getAll() {
        return employeeMapper.getAll();
    }

    @Transactional
    @Override
    public void patchDelete(Long[] ids) {
        for (Long id : ids) {
            delete(id);
        }
    }

    @Override
    public PageInfo<Employee> pageQuery(EmployeeQuery query) {
        //原生的写法：1.先查询总页数  2.再根据分页的信息查询当前页的数据
        //PageHelper的写法：开启分页
//                PageHelper.startPage(当前页,每页显示的条数);
        PageHelper.startPage(query.getCurrentPage(), query.getPageSize());
        //分页查询：只要开启了分页，它会帮助我们做什么事情？
        //1.先查询总数量  //2.根据application.yml中驱动名自动实现分页，如果是mysql就用limit
        //3.自动计算limit的第一个值：limit a,b [a = 当前页的起始下标 = (当前页-1)*每页显示的条数]
//        List<Emp> emps = empMapper.pageQuery(empQuery);
        List<Employee> list = employeeMapper.pageQuery(query);

        // 获取员工对应的角色和角色Id
        for (Employee employee : list) {
            // 传了对象才能查询到对应的字段
            // 通过员工id 获取角色的id和名称
           List<String> roles =  employeeMapper.getRoleNameByEmpId(employee.getId());
           List<Long> myRoles =  employeeMapper.getRoleByEmpId(employee.getId());

           // 将属性放到对象里面
           employee.setRoles(roles);
           employee.setMyRoles(myRoles);
        }
        return new PageInfo(list);
    }

}
